package Simulation;

import java.util.Vector;

import fxana.FxRawDataSet;
import fxana.RawDataCell;
import Simulation.ConditionState;

public class SimulationSystem {

	Vector<Condition> Settled;
	Vector<Condition> Working;
	EvaluatorParaFlag  EPFlag;
	public SimulationSystem(FxRawDataSet ds,EvaluatorParaFlag epflag,Condition seed){
		Settled=new Vector<Condition>();
		Working=new Vector<Condition>();
		EPFlag=epflag;
		Simulate(ds,seed);
	}
	
	private void Simulate(FxRawDataSet ds,Condition seed){
		Vector<RawDataCell> buffer=ds.GetRawDataBuffer();
		int it;
		for(it=0;it<buffer.size();it++){
			RawDataCell today=buffer.elementAt(it);
			int itj;
						
			/* Update the working ones */
			for(itj=0;itj<Working.size();itj++){
				Working.elementAt(itj).UpdateCondition(ds,today,this.EPFlag);				
			}
			
			/*Check the working ones first*/
			for(itj=0;itj<Working.size();itj++){
				ConditionState statj=Working.elementAt(itj).GetState();
				if(statj==ConditionState.SETTLED|| statj==ConditionState.LOSSBUY|| statj==ConditionState.LOSSSELL){
					Settled.add(Working.elementAt(itj));
					Working.remove(itj);
					itj--;
				}
			}
			
			/*Check today*/
			Condition tmp=seed.GetNew(ds,today,EPFlag);
			ConditionState state=tmp.GetState();
			if(state==ConditionState.SETTLED|| state==ConditionState.LOSSBUY|| state==ConditionState.LOSSSELL){
				Settled.add(tmp);
			}
			
			if(state==ConditionState.WAITBUY||state==ConditionState.WAITSELL){
				Working.add(tmp);
			}
		}
	}
	
	public Double GetTotalMerit(){
			Double TotalMerit=0.0;
			int itj;
			for(itj=0;itj<Settled.size();itj++){
				TotalMerit+=Settled.elementAt(itj).GetMerit();
			}
			return TotalMerit;
	}
	public void output(){
			Double TotalMerit=0.0;
			Double  TotalWinValue=0.0;
			int  TotalWinCount=0;
			Double TotalLoseValue=0.0;
			int TotalLoseCount=0;
			int WaitingCount=Working.size();
			
			int itj;
			for(itj=0;itj<Settled.size();itj++){
				TotalMerit+=Settled.elementAt(itj).GetMerit();
				if(Settled.elementAt(itj).IsWin()){
					TotalWinValue+=Settled.elementAt(itj).GetMerit();
					TotalWinCount++;
				}else{
					TotalLoseValue+=Settled.elementAt(itj).GetMerit();
					TotalLoseCount++;
				}
			}

			System.out.printf("%s -------Total Merit:%.2f   TotalWinValue:%.2f (%d wins)   TotalLoseValue:%.2f (%d loses) Merit rate:%.2f %d waits\n",
										EPFlag.GetOptionString(),
										TotalMerit, TotalWinValue,TotalWinCount,TotalLoseValue,TotalLoseCount, TotalMerit/(TotalWinCount+TotalLoseCount),WaitingCount);

			if(this.EPFlag.IsAFlagSet()){
				System.out.println("History:");
				System.out.println("-----------------");
				System.out.println("1. Settled:");
				this.OutputSettled();
				
				System.out.println();
				System.out.println("2. Waitting:");
				this.OutputWorking();
			}
	}
	public void OutputSettled(){
		if(this.Settled.isEmpty()){
			System.out.println("No one settled!");
			return;
		}

		int itj;
		/* print top title */
		this.Settled.elementAt(0).Output(0);
		/* print data */
		for(itj=0;itj<Settled.size();itj++){
			this.Settled.elementAt(itj).Output(1);
		}
		/* print bottle data */
		this.Settled.elementAt(0).Output(2);
		return;
	}
	
	public void OutputWorking(){
		if(this.Working.isEmpty()){
			System.out.println("No one is watting!");
			return;
		}
		
		int itj;
		this.Working.elementAt(0).Output(0);
		for(itj=0;itj<this.Working.size();itj++){
			this.Working.elementAt(itj).Output(1);
		}
		this.Working.elementAt(0).Output(2);
	}
	
	public Vector<Condition> GetCopyofWorking(){
		Vector<Condition> cp=new Vector<Condition>();
		int i;
		for(i=0;i<this.Working.size();i++){
			cp.add(this.Working.elementAt(i));
		}
		return cp;
	}
	
	public Vector<Condition> GetCopyofSettle(){
		Vector<Condition> cp=new Vector<Condition>();
		int i;
		for(i=0;i<this.Settled.size();i++){
			cp.add(this.Settled.elementAt(i));
		}
		return cp;
	}
}
